package cn.geminis.lowcode.compiler.code;

import cn.geminis.lowcode.compiler.Context;
import com.sun.source.tree.Tree;
import com.sun.source.util.Trees;
import lombok.NonNull;

import javax.lang.model.element.Element;
import java.util.Objects;

/**
 * @author puddi
 */
public abstract class AbstractCode<T extends Tree, S extends Element> {
    private T jdkTree;
    private S jdkElement;

    protected AbstractCode() {
    }

    protected AbstractCode(@NonNull Element element) {
        this.jdkElement = (S) element;
        this.jdkTree = (T) Trees.instance(Context.INSTANCE.getProcessingEnv()).getTree(element);
    }

    protected AbstractCode(@NonNull T tree) {
        this.jdkTree = tree;
    }

    public T getJdkTree() {
        if (Objects.isNull(this.jdkTree)) {
            this.jdkTree = createJdkTree();
        }
        return this.jdkTree;
    }

    protected void treeChanged() {
        this.jdkElement = null;
    }

    public S getJdkElement() {
        if (Objects.isNull(this.jdkElement)) {
            this.jdkElement = createJdkElement();
        }
        return this.jdkElement;
    }

    /**
     * 获取JDK Tree对象
     *
     * @return JdkTree对象
     */
    protected abstract T createJdkTree();

    /**
     * 创建JDK Element对象
     *
     * @return Element对象
     */
    protected abstract S createJdkElement();

}
